<!-- 二次封装表格自定义组件-->
<template>
    <div class="hyTable">
        <!--:ref                     -> 注册引用信息
            @header-click            -> 某列的表头被点击时触发的事件
            :resizble                -> 对应列是否可以通过拖动改变宽度 （需要在el - table 上设置border）
            :border                  -> 是否带有纵向边框
            :data                    -> 显示的数据
            tooltip-effect           -> tooltip effect 属性
            style                    -> 样式
            @select                  -> 当用户手动勾选数据行的CheckBox 时触发的事件
            :stripe                  -> 是否显示斑马纹
            :height                  -> Table 的高度，默认为自动高度。 如果height 为 number 类型， 单位 px; 如果 height 为 string 类型，则这个高度会设置为Talbe 的 style.height 的值，Table 的高度会受控于外部样式。
            size                     -> Table 的尺寸
            :highlight-current-row   -> 是否要高亮当前行
            @current-change          -> 当表格的当前行发生变化的时候会触发该事件，如果要高亮当前行，请打开表格的 highlight-current-row 属性
            @select-all              -> 当用户手动勾选全选Checkbox 时触发的事件
               -->
        <el-table :ref="type" @header-click="headerClick" :resizble="editSize"  :data="dataPage" tooltip-effect="light" style="width: 100%;" @select="tableChk" :stripe="stripe" :height="height" :highlight-current-row="singleElection" @current-change="singleChange" @select-all="tableAll">
            <!-- 选择框-->
            <el-table-column align="center" type="selection" width="55" v-if="checkbox"></el-table-column>
            <!-- 序号-->
            <el-table-column width="55" :label="tableIndex" sortable type="index" header-align="center" align="center" v-if="tableIndex"></el-table-column>
            <!--数据列  通过v-for实现列生成
                :show-overflow-tooltip   ->当内容过长被隐藏时显示 tooltip
                sortable
                :key
                :label
                header-align
                align
                :prop
                :width
                :min-width
                -->
            <el-table-column v-for="item in tableTitleChk" :key="item.id" :sortable='item.sortable' :label="item.label" header-align="center" align="center" :prop="item.prop" :show-overflow-tooltip="true" :width="item.width" :min-width="item.minWidth">
                <template slot-scope="scope">
                    <span v-if="item.tag===undefined&&item.switch===undefined">{{filterText(scope.row[item.prop], item.prop)}}</span>
                    <el-tag  v-if="item.tag!==undefined&&item.switch===undefined" :type="filterTag(scope.row[item.prop], item.tag)">{{filterText(scope.row[item.prop], item.prop)}}</el-tag>
                    <el-switch v-if="item.tag===undefined&&item.switch!==undefined" v-model="scope.row[item.prop]" active-text="开始" inactive-text="结束" :active-value="1" :inactive-value="0" @change="switchChange"></el-switch>
                </template>
            </el-table-column>
            <el-table-column label="操作" :width="width"  align="center" v-if="editColumn && editState" :fixed="fixed">
                <template slot-scope="scope">
                    <!-- 通用按钮——新增 -->
                    <el-button size="mini" type="warning" @click.stop="add(scope.row)" v-if="button.add">{{buttonText.add}}</el-button>
                    <!-- 通用按钮——编辑 -->
                    <el-button size="mini" type="warning" @click.stop="edit(scope.row)" v-if="button.edit">{{buttonText.edit}}</el-button>
                    <!-- 通用按钮——删除 -->
                    <el-button size="mini" type="warning" @click.stop="del(scope.row)" v-if="button.delete">{{buttonText.delete}}</el-button>
                    <!-- 通用按钮——查看 -->
                    <el-button size="mini" type="primary" @click.stop="look(scope.row)" v-if="button.look">{{buttonText.look}}</el-button>
                    <!-- 特殊功能专用按钮——根据字段 scope.row.*** 来判断是否显示 -->
                    <el-button size="mini" type="text" @click.stop="confirm(scope.row)" v-if="button.confirm && (scope.row.state === 1 || scope.row.state === 2)"></el-button>
                </template>
            </el-table-column>
        </el-table>
        <div style="text-align: center;height: 56px;padding: 20px 0 10px;box-sizing: border-box;bottom: 0px;left: 0px;right: 0px" v-if="pageState">
            <el-pagination 
              background
              @size-change="sizeG"
              @current-change="selectAjax"
              :layout="page.layout"
              :total="pageSize"
              ></el-pagination>   
              <!--:current-page.sync="page.index"
              :pager-count="5"
              :small="pageSmall"
              :page-sizes="page.sizes"
              :page-size="size ? size : page.size"-->
        </div> 
    </div>
</template>
<script>
/* 
   传入 button 对象类型参数有 {delete: true, add: true, edit: true, look: true} 必传
   传入 buttonText 对象类型参数有 {delete: '删除', add: '增加', edit: '编辑', look: '查看'} 可选
   传入 titleData 对象类型参数有 表头对象数组 必传
   传入 data 表格data数据 必传
   传入 tableIndex 表格索引序号  可选默认不显示 传入String 索引的表头名称
   传入 operation 表格操作列的宽度 可选 默认为 120
   传入 editSize 表格边框可拖动宽度 可选  默认无
   传入 type 表格ref类型 可选 默认无
   传入 pageSize 总长度 必传
   传入 pageIndex 当前页 默认1
   传入 checkbox 是否多选框 默认无
   传入 pageSmall 小分页  默认无
   传入 editColumn 是否支持自定义显示列 默认支持
   事件
   操作按钮事件delete edit look add 接受一个参数 表格行的数据
   表格已经选中的事件 多选框 selectData 接收一个参数  已经选择表格的参数
   每页显示数据多少个改变 limit 接受一个参数
   当前页改变 index 接收一个参数
*/
export default {
    name:'hyTable',
    props:{
        button:{
            type: [Array, Object],
            default: () => { return {delete: false, add:false, edit:false, look: false} }
        },
        btnCustom: {
            type: [Array, Object],
            default: () => { return [] }
        },
        buttonType: {
            type: [Array, Object],
            default: () => { return {} }
        },
        titleData:{
            type: [Array, Object],
            default: () => { return [] }
        },
        data: {
            type: [Array, Object],
            required:true,
            default: () => { return [] }
        },
        buttonText: {
            type: [Array, Object],
            default: () => { return {delete: '删除', add: '增加', edit: '编辑', look: '查看'} }
        },
        filter: {
            type: [Array, Object],
            default: () => { return {} }
        },
        stripe: {
            type: Boolean,
            default: true
        },
        checkbox: {
            type: Boolean,
            default: false
        },
        singleElection: {
            type: Boolean,
            default:false
        },
        tableIndex: {
            type: [String, Boolean],
            default: false
        },
        operation: {
            type: [Number, String],
            default: 0
        },
        editSize: {
            type: Boolean,
            default: true
        },
        editState: {
            type: Boolean,
            default: true
        },
        editColumn: {
            type: Boolean,
            default: true
        },
        pageSmall: {
            type: Boolean,
            default: true
        },
        pageState: {
            type: Boolean,
            default: true
        },
        type: {
            type: String,
            default: 'table'
        },
        pageSize: {
            type: Number,
            default: 0
        },
        size: {
            type: Number
        },
        pageIndex: {
            type: Number,
            default: 1
        },
        height: {
            type: Number
        },
        isEditColumn: {
            type: Boolean,
            default: false
        },
        buttonFilter: {
            type: [Array, Object],
            default: () => { return {} }
        },
        buttonCancel: {
            type: Object,
            default: () => { return {} }
        },
        fixed: {
            type: String
        }
    },
    components: {
    },
    data () {
        return {
            page: {
                size: 10 ,
                sizes: [10, 30, 50, 100, 200, 500, 1000],
                index: 1,
                layout: 'prev, pager, next'    //total, sizes, prev, pager, next, jumper'
            },
            tableTitleChk: [],
            tableTitle: [],
            width:120,
            selectData: [],
            dataPage: [],
            pageNum: 100,
            currentPage: 0,
            pageTotal: 0
        }
    },
    computed: {
    },
    created () {
        console.log("---->page<----");
        console.log(this.page);
        this.dataPage = this.data
        this.tableTitleChk = this.titleData
        this.tableTitle = this.titleData
        this.buttonComp()
        this.columnWidth()
    },
    mounted () {
    },
    activated () {

    },
    methods: {
        scrollAdd () {
            if (this.data.length > 100) {
                let elm = document.querySelector('el-table__body-warapper')
                let _this = this
                let isload = true
                elm.addEventListener('scroll', () => {
                    let wrapHeight = elm.offsetHeight
                    let scrollTop = elm.scrollTop
                    let scrollHeight = elm.scrollHeight
                    let isHeight = scrollHeight - wrapHeight - scrollTop - 200
                    if (isHeight < 0 && _this.currentPage <= _this.pageTotal && isload) {
                        let dataPage = _this.data.slice(_this.currentPage * _this.pageNum, (_this.currentPage + 1) * _this.pageNum)
                        _this.currentPage++
                        isload = false 
                        let timer = setTimeout(function () {
                            isload = true
                            clearTimeout(timer)
                        }, 2000)
                        _this.dataPage = _this.dataPage.concat(dataPage)
                    }
                })
            }
        },
        filterTag (val, tag) {
            if(val === true || val === tag) {
                return 'seccess'
            }
            return 'danger'
        },
        columnWidth() {
            let len = this.tableTitle.length
            let width = 20
            let arrow = 20
            if (len > 6) {
                for(let i = 0; i < len; i++) {
                    if (i === len -1) {
                        this.tableTitle[i].width = ''
                        let lastWidth = width * this.tableTitle[i].label.length + arrow
                        lastWidth = lastWidth > 100 ? lastWidth :100
                        this.tableTitle[i].minWidth = lastWidth
                    } else {
                        if (!this.titleData[i].width) {
                            let itemWith = 0
                            if (this.tableTitle[i].label.length > 3) {
                                itemWith = width * this.tableTitle[i].label.length + arrow
                            }else {
                                itemWith = 30 * this.tableTitle[i].label.length + arrow
                            }
                            this.tableTitle[i].width = itemWith > 80 ? itemWith :80
                        }
                    }
                }
            }
        },
        headerClick (column, event) {
            if (this.isEditColumn && column.order !== '') {
                if(this.selectData && this.selectData.length > 0) {
                    this.$emit('column', column)
                }else {
                    this.$alert('请选择需要修改的列', '提示', {confirmButtonText: '确定', showClose: false})
                }
            }
        },
        timeAll (val) {
            if(val !== null && val !== undefined) {
                var date = new Date(val)
                var seperator1 = '-'
                var month = date.getMonth() +1
                var strDate = date.getDate()
                if (month >= 1 && month <= 9) {
                    month = '0' + month
                }
                if (strDate >= 0 && strDate <= 9) {
                    strDate = '0'+ strDate
                }
                var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate
                return currentdate
            }else {
                return ''
            }
        },
        filterText (val, name) {
            if( this.filter[name] === undefined){
                return val
            } else {
                return this.filter[name](val)
            }
        },
        buttonComp () {
            let num = 0
            if(this.button.edit) num ++
            if(this.button.add) num ++
            if(this.button.delete) num ++
            if(this.button.look) num ++
            num = num + this.btnCustom.length
            num = num * 50
            if (this.operation === 0) {
                this.width = num === 50 ? 100 : num
            } else {
                this.width = this.operation
            }
        },
        renderHeader (createElement, data) {
            let self = this
            return createElement(
                'pop-btn',
                {
                    props: {
                        value: self.tableTitleChk,
                        data: self.tableTitle,
                        title: data.column.label
                    },
                    on: {
                        input: (a) => {
                            self.tableTitleChk = a
                        }
                    }
                },''
            )
        },
        sure (a) {
            this.$emit('sure', a)
        },
        lookText (a) {
            this.$emit('lookText', a)
        },
        upload (a) {
            this.$emit('upload', a)
        },
        reset (a) {
            this.$emit('reste', a)
        },
        distr (a) {
            this.$emit('distr', a)
        },
        addText (a) {
            this.$emit('addText', a)
        },
        taskDown (a) {
            this.$emit('taskDown', a)
        },
        taskBackDown (a) {
            this.$emit('taskBackDown', a)
        },
        cancel (a) {
            this.$emit('cancelOrders', a)
        },
        isBtn (a) {
            this.$emit('isBtn', a)
        },
        look (a) {
            this.$emit('look', a)
        },
        add (a) {
            this.$emit('add', a)
        },
        del (a) {
            this.$confirm('是否删除选中记录，请确认？', '提示', {
                confirmButtonText: '确认',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                this.$emit('delete', a)
            }).catch(() => {

            })
        },
        edit (a) {
            this.$emit('edit', a)
        },
        tableChk (a) {
            this.selectData = a
            this.$emit('selectData', a)
        },
        tableAll (a) {
            if(this.data.length > this.pageNum) {
                this.selectData = this.data
            } else {
                this.selectData = a
            }
            this.$emit('selectData', this.selectData)
        },
        sizeG (a) {
            this.page.size = a
            this.$emit('limit', {'limit': a, 'index': 1})
        },
        selectAjax (a) {
            this.$emit('limit', {'limit': this.size ? this.size : this.page.size, 'index': a})
        },
        singleChange (now, last) {
            this.$emit('singleChange', now, last)
        },
        clearSelection () {
            this.$refs[this.type].clearSelection()
        },
        farm (a) {
            this.$emit('farm', a)
        },
        confirm (a) {
            this.$emit('confirm', a)
        }
    },
    watch: {
        data(val) {
            if (val.length > 100) {
                if(this.currentPage === 0) {
                    this.scrollAdd()
                }
                this.currentPage = 0
                this.dataPage = val.slice(this.currentPage * this.pageNum, (this.currentPage + 1) * this.pageNum)
                this.pageTotal = Math.ceil(val.length / this.pageNum)
                this.currentPage++
            } else {
                this.dataPage = val
            }
        },
        titleData: {
            handler (cval, oval) {
                if (cval !== oval){
                    this.tableTitle = this.titleData
                    this.tableTitleChk = this.titleData
                    this.columnWidth()
                }
            },
            deep: true
        },
        pageIndex () {
            this.page.index = this.pageIndex
        }
    }
}
</script>

<style lang='scss'>
.hyTable {
    min-height:  100%;
    width: 100%;
    position: relative;
    .el-table_body-wrapper{
        position: absolute;
    }
    .el-pagination .el-select .el-input .el-input__inner{
        height: 20px;
    }
    .el-select .el-input .el-select__caret{
        line-height: 1;
    }
}

</style>